package com.codi.bus.core.service.organ.impl;

import com.codi.base.util.EqualsUtil;
import com.codi.base.util.StringUtil;
import com.codi.bus.constant.GlobalConstant;
import com.codi.bus.constant.PayTypeConst;
import com.codi.bus.constant.RuleConstant;
import com.codi.bus.core.dao.LookupDao;
import com.codi.bus.core.dao.OrganBankDao;
import com.codi.bus.core.domain.*;
import com.codi.bus.core.resultModel.BaseResult;
import com.codi.bus.core.service.*;
import com.codi.bus.core.service.model.PayMethodModel;
import com.codi.bus.core.service.organ.OrganPaymentService;
import com.codi.bus.core.service.organ.OrganProfileService;
import com.codi.message.constant.ErrorConstant;
import com.codi.message.util.MessageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by asus on 2018/5/8.
 */
@Service("organPaymentService")
@Slf4j
public class OrganPaymentServiceImpl implements OrganPaymentService{

    @Autowired
    private UserService userService;

    @Autowired
    private BankService bankService;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private OrganBankDao organBankDao;

    @Autowired
    private WalletService walletService;

    @Autowired
    private LookupDao lookupDao;

    @Autowired
    private LookupService lookupService;

    @Autowired
    private OrganProfileService organProfileService;



    @Override
    @Transactional(readOnly = true)
    public BaseResult getOrganPayMethodsForWallet(Long userId, Long profileId) {
        BaseResult result = new BaseResult(false);

        User userEntity = userService.getUser(userId);
        OrganProfile organProfile = organProfileService.getById(profileId);
        if (StringUtil.isEmpty(organProfile.getProfileId().toString())) {
            result.setErrorCode(ErrorConstant.ERROR_NO_ACCOUNT);
            result.setErrorMessage(MessageUtil.getErrorMsg(ErrorConstant.ERROR_NO_ACCOUNT));
            return result;
        }

        List<OrganBank> organBankList = organBankDao.selectUsableByProfileId(profileId);
        //List<UserBank> banks = bankService.getListByUserId(userId);

        result.setSuccess(true);

        List<PayMethodModel> payMethods = new ArrayList<>();
        if (CollectionUtils.isEmpty(organBankList)) {
            result.setResult(payMethods);
            return result;
        }



        //添加一条线下汇款方式
        payMethods = payByOffline(organBankList);
//        payMethods.add(addOneOffline(organBankList.get(0)).setPayMethodModels(payByOffline(organBankList)));
        payMethods.get(0).setPayMethodModels(payByOffline(organBankList));
        payMethods.forEach(payMethodModel -> {
            payMethodModel.setIsInside(false);
            if (payMethodModel.getPayMethodModels() != null){
                payMethodModel.getPayMethodModels().forEach(item -> {
                    item.setIsInside(true);
                });
            }
        });

        result.setResult(payMethods);
        return result;
    }


    @Override
    @Transactional(readOnly = true)
    public BaseResult getOrganPayMethodsForFund(Long userId, Long profileId) {

        BaseResult result = new BaseResult(false);

        User userEntity = userService.getUser(userId);



        result.setSuccess(true);
        List<OrganBank> organBankList = organBankDao.selectUsableByProfileId(profileId);
        List<PayMethodModel> payMethods = new ArrayList<>();
        if (CollectionUtils.isEmpty(organBankList)) {
            result.setResult(payMethods);
            return result;
        }

        // 所有的支付方式


        //添加一条线下汇款方式
        payMethods = payByOffline(organBankList);


        payMethods.get(0).setPayMethodModels(payByOffline(organBankList));
//        payMethods.add(payByOffline(organBankList).get(0).setPayMethodModels(payByOffline(organBankList)));




        payMethods.forEach(payMethodModel -> {
            payMethodModel.setIsInside(false);
            if (payMethodModel.getPayMethodModels() != null){
                payMethodModel.getPayMethodModels().forEach(item -> {
                    item.setIsInside(true);
                });
            }
        });
        result.setSuccess(true);
        result.setResult(payMethods);

        return result;
    }

    private List<PayMethodModel> payByOffline(List<OrganBank> banks) {
        List<PayMethodModel> pays = new ArrayList<>(banks.size());

        Lookup lookup = lookupService.getLookup(RuleConstant.TYPE_OFFLINE_BUY, RuleConstant.VALUE_OFFLINE_BUY_MIN_VALUE);
        String singleDealMinValue = "-1";

        PayMethodModel payMethodModel;
        for (OrganBank bank : banks) {

            if (EqualsUtil.equals(bank.getUbCapitalMode(), GlobalConstant.CAPITAL_MODE_COUNTER)) {
                continue;
            }

            payMethodModel = PayMethodModel.builder()
                .payType(PayTypeConst.OFFLINE)
                .payName(PayTypeConst.OFFLINE_LABEL)
                .bankCode(bank.getUbBankCode())
                .bankName(bank.getUbBankName())
                .bankNo(bank.getUbOrganBankNo())
                .capitalMode(bank.getUbCapitalMode())
                .tradeAcco(bank.getExternalTradeAccount())
                //单笔最小值
                .singleDealMinValue(new BigDecimal(singleDealMinValue))
                .canUse(true)
                .build();
            pays.add(payMethodModel);
        }
        return pays;
    }


    private PayMethodModel addOneOffline(OrganBank bank) {

        Lookup lookup = lookupService.getLookup(RuleConstant.TYPE_OFFLINE_BUY, RuleConstant.VALUE_OFFLINE_BUY_MIN_VALUE);
        String singleDealMinValue = "-1";
        if (lookup != null) {
            singleDealMinValue = lookup.getComponentValue();
        }

        PayMethodModel payMethodModel;
        payMethodModel = PayMethodModel.builder()
            .payType(PayTypeConst.OFFLINE)
            .payName(PayTypeConst.OFFLINE_LABEL)
            .bankCode(bank.getUbBankCode())
            .bankName(bank.getUbBankName())
            .bankNo(bank.getUbOrganBankNo())
            .capitalMode(bank.getUbCapitalMode())
            .tradeAcco(bank.getExternalTradeAccount())
            //单笔最小值
            .singleDealMinValue(new BigDecimal(singleDealMinValue))
            .canUse(true)
            .build();
        return payMethodModel;
    }

}
